# Maintainer: Alexey Pavlov <alexpux@gmail.com>

_realname=clang
pkgbase="mingw-w64-${_realname}35"
pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}35"
         "${MINGW_PACKAGE_PREFIX}-clang-analyzer35"
         "${MINGW_PACKAGE_PREFIX}-clang-tools-extra35"
         "${MINGW_PACKAGE_PREFIX}-llvm35"
         )
pkgver=3.5.2
pkgrel=1
pkgdesc="LC language family frontend for LLVM (mingw-w64)"
arch=('any')
url="https://llvm.org/"
license=("custom:University of Illinois/NCSA Open Source License")
makedepends=("${MINGW_PACKAGE_PREFIX}-gcc"
             "${MINGW_PACKAGE_PREFIX}-pkg-config"
             "${MINGW_PACKAGE_PREFIX}-python3-sphinx"
             "python2" "tar")
depends=("${MINGW_PACKAGE_PREFIX}-gcc")
options=('staticlibs' 'strip')
source=(https://releases.llvm.org/${pkgver}/llvm-${pkgver}.src.tar.xz{,.sig}
        https://releases.llvm.org/${pkgver}/cfe-${pkgver}.src.tar.xz{,.sig}
        https://releases.llvm.org/${pkgver}/clang-tools-extra-${pkgver}.src.tar.xz{,.sig}
        0000-llvm-3.5.0-force-link-pass.o.patch
        0001-clang-fabs.patch
        0002-clang-win64-seh.patch
        0003-clang-mingw-driver.patch
        0004-gcc5-compatibility.patch)
sha256sums=('44196156d5749eb4b4224fe471a29cc3984df92570a4a89fa859f7394fc0c575'
            'SKIP'
            '4feb575f74fb3a74b6245400460230141bf610f235ef3a25008cfe6137828620'
            'SKIP'
            'f21a374d74b194d8c984546266491b518859b5f12ed9abd49337b8060d3fc004'
            'SKIP'
            '5702053503d49448598eda1b8dc8c263f0df9ad7486833273e3987b5dec25a19'
            '614a076dc65b400910b190f4e3d26fdebd20885cfd482f7f8464469808e3beac'
            '6e1168e5c9cba875ef7e87ccfd3060c3a0db6b5e2c3f1fa9fdb4d0eaea465025'
            '2f49bba3acb0e45b0c3374537f2f9036891013c751930437c80472d8d8d8e2a7'
            'c964eecdfb0cbf4d2a59a553d7bdb3f16e70d8910e6aa7e9c768828ecbdfcea2')

noextract=(cfe-${pkgver}.src.tar.xz)

prepare() {
  plain "Extracting clang-${pkgver}.src.tar.xz due to symlink(s) without pre-existing target(s)"
  [[ -d ${srcdir}/cfe-${pkgver} ]] && rm -rf ${srcdir}/cfe-${pkgver}
  [[ -d ${srcdir}/cfe-${pkgver} ]] || tar -xJvf ${srcdir}/cfe-${pkgver}.src.tar.xz -C ${srcdir} || true

  sleep 10
  cd "${srcdir}/llvm-${pkgver}.src"
  # At the present, clang must reside inside the LLVM source code tree to build
  # See https://bugs.llvm.org/show_bug.cgi?id=4840
  [[ -d tools/clang ]] && rm -rf tools/clang
  mv "${srcdir}/cfe-${pkgver}.src" tools/clang

  [[ -d tools/clang/tools/extra ]] && rm -rf tools/clang/tools/extra
  mv "${srcdir}/clang-tools-extra-${pkgver}.src" tools/clang/tools/extra

  # Fix docs installation directory
  sed -i 's:$(PROJ_prefix)/docs/llvm:$(PROJ_prefix)/share/doc/llvm:' \
    Makefile.config.in

  # Fix definition of LLVM_CMAKE_DIR in LLVMConfig.cmake
  sed -i '/@LLVM_CONFIG_CMAKE_DIR@/s:$(PROJ_cmake):$(PROJ_prefix)/share/llvm/cmake:' \
    cmake/modules/Makefile

  # Fix build with GCC 4.9 (patch from Debian)
  # https://bugs.llvm.org/show_bug.cgi?id=20067
  patch -p1 -i "${srcdir}/0000-llvm-3.5.0-force-link-pass.o.patch"
  patch -p0 -i "${srcdir}/0004-gcc5-compatibility.patch"

  cd tools/clang
  patch -p1 -i ${srcdir}/0001-clang-fabs.patch
  patch -p1 -i ${srcdir}/0002-clang-win64-seh.patch
  patch -p1 -i ${srcdir}/0003-clang-mingw-driver.patch
}

build() {
  cd "${srcdir}"
  mkdir -p build-${MINGW_CHOST}
  cd build-${MINGW_CHOST}
  echo 'ac_cv_have_decl_strerror_s=${ac_cv_have_decl_strerror_s=no}' > config.cache

  # Include location of libffi headers in CPPFLAGS
  CPPFLAGS+=" $(pkg-config --cflags libffi)"

  ../llvm-${pkgver}.src/configure \
    -C \
    --prefix=${MINGW_PREFIX} \
    --build=${MINGW_CHOST} \
    --host=${MINGW_CHOST} \
    --with-sysroot=${MINGW_PREFIX} \
    --enable-targets=x86,x86_64,arm,mips \
    --enable-optimized \
    --disable-assertions \
    --disable-pthreads \
    --with-python=/usr/bin/python2 \
    --enable-libffi \
    --enable-docs

  make
  make -C ../llvm-${pkgver}.src/docs -f Makefile.sphinx man
  make -C ../llvm-${pkgver}.src/docs -f Makefile.sphinx html
  make -C ../llvm-${pkgver}.src/tools/clang/docs -f Makefile.sphinx html
  setup
}

check() {
  plain "skipping make check..."
  #cd "$srcdir/build-${MINGW_CHOST}"
  #make check
}

setup() {
  local destdir=${srcdir}/dest
  [[ -d ${destdir} ]] && rm -rf ${destdir}
  mkdir -p ${destdir}

  # CLANG-TOOLS-EXTRA
  cd "$srcdir/build-${MINGW_CHOST}/tools/clang/tools/extra"
  make DESTDIR="$destdir/clang-tools-extra" install
  # Fix permissions of static libs
  chmod -x ${destdir}/clang-tools-extra${MINGW_PREFIX}/lib/*.a
  install -Dm644 ${srcdir}/llvm-${pkgver}.src/tools/clang/tools/extra/LICENSE.TXT "$destdir/clang-tools-extra${MINGW_PREFIX}/share/licenses/clang-tools-extra/LICENSE"
  cd ${srcdir}
  mv ${srcdir}/build-${MINGW_CHOST}/tools/clang/tools/extra ${srcdir}/clang-tools-extra-${MINGW_CHOST}
  mv ${srcdir}/llvm-${pkgver}.src/tools/clang/tools/extra ${srcdir}/clang-tools-extra-${pkgver}

  # CLANG
  cd "$srcdir/build-${MINGW_CHOST}/tools/clang"
  make -j1 DESTDIR="$destdir/clang" install
  # Fix mis-named clang doc folder (is llvm, should be clang)
  mv ${destdir}/clang${MINGW_PREFIX}/share/doc/llvm ${destdir}/clang${MINGW_PREFIX}/share/doc/clang

  # Install html docs
  install -d "${destdir}"/clang${MINGW_PREFIX}/share/doc/clang/html
  cp -rf ${srcdir}/llvm-${pkgver}.src/tools/clang/docs/_build/html/* "${destdir}"/clang${MINGW_PREFIX}/share/doc/clang/html/
  rm -r "${destdir}"/clang${MINGW_PREFIX}/share/doc/clang/html/_sources

  # CLANG-ANAYLYSER
  install -d ${destdir}/clang-analyzer${MINGW_PREFIX}/{bin,lib/clang-analyzer}
  for _tool in scan-{build,view}; do
    cp -r ${srcdir}/llvm-${pkgver}.src/tools/clang/tools/${_tool} ${destdir}/clang-analyzer${MINGW_PREFIX}/lib/clang-analyzer/
    ln -s ${destdir}/clang-analyzer${MINGW_PREFIX}/lib/clang-analyzer/${_tool}/${_tool} ${destdir}/clang-analyzer${MINGW_PREFIX}/bin/
  done

  # scan-build looks for clang within the same directory
  install -d ${destdir}/clang-analyzer${MINGW_PREFIX}/lib/clang-analyzer/scan-build/
  ln -s ${destdir}/clang${MINGW_PREFIX}/bin/clang.exe ${destdir}/clang-analyzer${MINGW_PREFIX}/lib/clang-analyzer/scan-build/

  # Relocate man page
  install -d ${destdir}/clang-analyzer${MINGW_PREFIX}/share/man/man1
  mv ${destdir}/clang-analyzer${MINGW_PREFIX}/lib/clang-analyzer/scan-build/scan-build.1 \
    ${destdir}/clang-analyzer${MINGW_PREFIX}/share/man/man1/

  # Compile Python scripts
  python2 -m compileall "${destdir}/clang-analyzer${MINGW_PREFIX}/lib/clang-analyzer"
  python2 -O -m compileall "${destdir}/clang-analyzer${MINGW_PREFIX}/lib/clang-analyzer"
  install -Dm644 ${srcdir}/llvm-${pkgver}.src/tools/clang/LICENSE.TXT "${destdir}/clang-analyzer${MINGW_PREFIX}/share/licenses/clang-analyzer/LICENSE"

  # LLVM
  cd ${srcdir}
  # Move clang out of the way *before* installing llvm, both src and build. We'll put build back afterwards to allow re-packaging.
  # but the src move is undoing what prepare() did.
  mv "${srcdir}/build-${MINGW_CHOST}/tools/clang"   "${srcdir}/clang-${MINGW_CHOST}"
  mv "${srcdir}/llvm-${pkgver}.src/tools/clang"         "${srcdir}/clang-${pkgver}"       # Put src back where it was (clang)
  cd "${srcdir}/build-${MINGW_CHOST}"
  make -j1 DESTDIR="${destdir}/llvm" install

  # Install man pages
  install -d "${destdir}"/llvm${MINGW_PREFIX}/share/man/man1
  cp ${srcdir}/llvm-${pkgver}.src/docs/_build/man/*.1 "${destdir}"/llvm${MINGW_PREFIX}/share/man/man1/

  # Install html docs
  install -d "${destdir}"/llvm${MINGW_PREFIX}/share/doc/llvm/html
  cp -rf ${srcdir}/llvm-${pkgver}.src/docs/_build/html/* "${destdir}"/llvm${MINGW_PREFIX}/share/doc/llvm/html/
  rm -r "${destdir}"/llvm${MINGW_PREFIX}/share/doc/llvm/html/_sources

  # Install CMake stuff
  install -d "${destdir}"/llvm${MINGW_PREFIX}/share/llvm/cmake/{modules,platforms}
  install -Dm644 ${srcdir}/llvm-${pkgver}.src/cmake/modules/*.cmake "${destdir}"/llvm${MINGW_PREFIX}/share/llvm/cmake/modules/
  install -Dm644 ${srcdir}/llvm-${pkgver}.src/cmake/platforms/*.cmake "${destdir}"/llvm${MINGW_PREFIX}/share/llvm/cmake/platforms/

  # Move all back
  mv "${srcdir}/clang-${MINGW_CHOST}"                "${srcdir}/build-${MINGW_CHOST}/tools/clang"
  mv "${srcdir}/clang-${pkgver}"                     "${srcdir}/llvm-${pkgver}.src/tools/clang"
  mv "${srcdir}/clang-tools-extra-${MINGW_CHOST}"    "${srcdir}/build-${MINGW_CHOST}/tools/clang/tools/extra"
  mv "${srcdir}/clang-tools-extra-${pkgver}"         "${srcdir}/llvm-${pkgver}.src/tools/clang/tools/extra"
}

package_clang35(){
  pkgdesc="C language family frontend for LLVM"
  depends=("${MINGW_PACKAGE_PREFIX}-llvm35=${pkgver}-${pkgrel}")
  conflicts=(${MINGW_PACKAGE_PREFIX}-clang)

  mv ${srcdir}/dest/clang/* ${pkgdir}
}

package_llvm35(){
  pkgdesc="Low Level Virtual Machine"
  depends=("${MINGW_PACKAGE_PREFIX}-gcc")
  conflicts=(${MINGW_PACKAGE_PREFIX}-llvm)
  install=llvm-${CARCH}.install

  mv ${srcdir}/dest/llvm/* ${pkgdir}
}

package_clang-analyzer35() {
  pkgdesc="A source code analysis framework"
  url="https://clang-analyzer.llvm.org/"
  depends=("${MINGW_PACKAGE_PREFIX}-clang35=${pkgver}-${pkgrel}" "${MINGW_PACKAGE_PREFIX}-python2")
  conflicts=(${MINGW_PACKAGE_PREFIX}-clang-analyzer)

  mv ${srcdir}/dest/clang-analyzer/* ${pkgdir}
}

package_clang-tools-extra35() {
  pkgdesc="Extra tools built using Clang's tooling APIs"
  url="https://clang.llvm.org/"
  depends=("${MINGW_PACKAGE_PREFIX}-clang35=${pkgver}-${pkgrel}")
  conflicts=(${MINGW_PACKAGE_PREFIX}-clang)

  mv ${srcdir}/dest/clang-tools-extra/* ${pkgdir}
}

package_mingw-w64-i686-clang35(){
  package_clang35
}

package_mingw-w64-i686-clang-analyzer35(){
  package_clang-analyzer35
}

package_mingw-w64-i686-clang-tools-extra35(){
  package_clang-tools-extra35
}

package_mingw-w64-i686-llvm35(){
  package_llvm35
}

package_mingw-w64-x86_64-clang35(){
  package_clang35
}

package_mingw-w64-x86_64-clang-analyzer35(){
  package_clang-analyzer35
}

package_mingw-w64-x86_64-clang-tools-extra35(){
  package_clang-tools-extra35
}

package_mingw-w64-x86_64-llvm35(){
  package_llvm35
}
